<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\model\ProjectFace;
use app\model\ProjectHappy;
use app\model\ProjectHappyOut;
use app\model\ProjectHealth;
use app\model\ProjectHealthFood;
use app\model\ProjectHealthFoodNutrition;
use app\model\ProjectHealthPredicted;
use app\model\ProjectLife;
use app\model\ProjectLifeOut;
use app\model\ProjectMedical;
use app\model\ProjectRoom;
use app\model\User;
use app\tool\Http;
use app\tool\Random;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Promise\Promise;
use GuzzleHttp\Promise\Utils;
use GuzzleHttp\Psr7\Stream;
use thans\jwt\facade\JWTAuth;
use think\facade\Log;
use think\Request;

class CheckController extends BaseController
{
	protected $middleware = ['Login' => [
		'except' => ['happy', 'happyFill', 'life', 'lifeFill'],
	]];
	
	/**
	 * 面容健康检查
	 * @param Request $request
	 * @return void
	 */
	function face(Request $request)
	{
		$image = $request->file('image');
		if (empty($image)) {
			$this->writeJson('请先上传图片');
		}
		
		$client = new Client();
		$response = $client->post(config('app.static_host').'/api/common/upload', [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => fopen($image->getRealPath(), 'r'),
					'filename' => $image->getOriginalName()
				],
			]
		]);
		$upload = json_decode($response->getBody()->getContents());
		if ($upload->code != 1) {
			$this->writeJson(0, $upload->msg);
		}
		// 创建多个请求，请求地址可以相同，也可以不同
		$promises = [
			$client->postAsync('http://124.222.206.164:8000/upload_prediction', [
				'multipart' => [
					[
						'name' => 'file',
						'contents' => fopen($image->getRealPath(), 'r'),
						'filename' => $image->getOriginalName()
					],
				]
			]),
			$client->postAsync('http://124.222.206.164:3030/develop_facial_detection', [
				'multipart' => [
					[
						'name' => 'file',
						'contents' => fopen($image->getRealPath(), 'r'),
						'filename' => $image->getOriginalName()
					],
				]
			])
		];
		
		
		$results = Utils::unwrap($promises);
		
		list($age, $face) = $results;
		
		$face = json_decode($face->getBody()->getContents());
		if ($face->status != 1) {
			$this->writeJson(0, $face->message);
		}
		
		$age = json_decode($age->getBody()->getContents());
		if ($age->status != 1) {
			$this->writeJson(0, $age->error);
		}
		$age_predict = round($age->predict);
		$user = User::findOrFail($this->user_id);
		list($year, $month, $day) = explode('-', $user->birthday);
		$true_age = date('Y') - $year;
		$month_diff = date('m') - $month;
		$day_diff = date('d') - $day;
		if ($day_diff < 0 || $month_diff < 0) {
			$true_age--;
		}
		if ($true_age > $age_predict - 3 && $true_age < $age_predict + 3) {
			$face_age = '年龄相仿';
		}
		if ($true_age < $age_predict - 3) {
			$face_age = '略显成熟';
		}
		if ($true_age > $age_predict + 3) {
			$face_age = '稍显年轻';
		}
		
		$ret = ProjectFace::create([
			'user_id' => $this->user_id,
			'image' => $upload->data->url,
			'face_name' => $face->facial_data->face_name,
			'left_eye_name' => $face->facial_data->left_eye_name,
			'left_eyebrow_name' => $face->facial_data->left_eyebrow_name,
			'mouth_name' => $face->facial_data->mouth_name,
			'nose_name' => $face->facial_data->nose_name,
			'right_eye_name' => $face->facial_data->right_eye_name,
			'right_eyebrow_name' => $face->facial_data->right_eyebrow_name,
			'true_age' => $true_age,
			'age_predict' => $age_predict,
			'face_age' => $face_age,
		]);
		$this->writeJson($ret);
	}
	
	
	/**
	 * 居家检测
	 * @return void
	 */
	function room(Request $request)
	{
		$image = $request->file('image');
		if (empty($image)) {
			$this->writeJson('请先上传图片');
		}
		
		$client = new Client();
		$response = $client->post(config('app.static_host').'/api/common/upload', [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => fopen($image->getRealPath(), 'r'),
					'filename' => $image->getOriginalName()
				],
			]
		]);
		$upload = json_decode($response->getBody()->getContents());
		if ($upload->code != 1) {
			$this->writeJson(0, $upload->msg);
		}
		ProjectRoom::create([
			'user_id' => $this->user_id,
			'predict' => '圖片上傳成功',
			'image' => $upload->data->url
		]);
		$this->writeJson(1, '', '圖片上傳成功');
	}
	
	/**
	 * 医疗报告
	 * @return void
	 */
	function medical(Request $request)
	{
		$image = $request->file('image');
		if (empty($image)) {
			$this->writeJson('请先上传图片');
		}
		
		$client = new Client();
		$upload = $client->post(config('app.static_host').'/api/common/upload', [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => fopen($image->getRealPath(), 'r'),
					'filename' => $image->getOriginalName()
				],
			]
		]);
		$upload = json_decode($upload->getBody()->getContents());
		if ($upload->code != 1) {
			$this->writeJson(0, $upload->msg);
		}
		ProjectMedical::create([
			'user_id' => $this->user_id,
			'predict' => '圖片上傳成功',
			'image' => $upload->data->url
		]);
		$this->writeJson(1, '', '圖片上傳成功');
	}
	
	/**
	 * 营养健康
	 * @return void
	 */
	function health(Request $request)
	{
		$image = $request->file('image');
		if (empty($image)) {
			$this->writeJson('请先上传图片');
		}
		
		$client = new Client();
		$upload = $client->post(config('app.static_host').'/api/common/upload', [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => fopen($image->getRealPath(), 'r'),
					'filename' => $image->getOriginalName()
				],
			]
		]);
		$upload = json_decode($upload->getBody()->getContents());
		if ($upload->code != 1) {
			$this->writeJson(0, $upload->msg);
		}
		$s = microtime(true);
		$foods = $client->post('http://124.222.206.164:5000/develop_classification', [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => fopen($image->getRealPath(), 'r'),
					'filename' => $image->getOriginalName()
				],
			]
		]);
		$use = microtime(true) - $s;
		$foods = json_decode($foods->getBody()->getContents());
		$foods = $foods->Top10_Prediction_Result_Nutritions;
		
		$data = [];
		foreach ($foods as $food) {
			$data[] = [
				'name' => $food->Name,
				'calcium' => $food->nutrition->{'Calcium(mg)'},
				'carbohydrates' => $food->nutrition->{'Carbohydrates(g)'},
				'cholesterol' => $food->nutrition->{'Cholesterol(mg)'},
				'copper' => $food->nutrition->{'Copper (mg)'},
				'dietary_fiber' => $food->nutrition->{'Dietary Fiber(g)'},
				'energy' => $food->nutrition->{'Energy(kcal)'},
				'fat' => $food->nutrition->{'Fat(g)'},
				'iron' => $food->nutrition->{'Iron(mg)'},
				'magnesium' => $food->nutrition->{'Magnesium (mg)'},
				'manganese' => $food->nutrition->{'Manganese(mg)'},
				'phosphorus' => $food->nutrition->{'Phosphorus (mg)'},
				'potassium' => $food->nutrition->{'Potassium(mg)'},
				'protein' => $food->nutrition->{'Protein(g)'},
				'saturated' => $food->nutrition->{'Saturated fat(g)'},
				'sodium' => $food->nutrition->{'Sodium(mg)'},
				'sugar' => $food->nutrition->{'Sugar(g)'},
				'trans_fat' => $food->nutrition->{'Trans fat(g)'},
				'vitamin_c' => $food->nutrition->{'Vitamin C(mg)'},
				'zinc' => $food->nutrition->{'Zinc(mg)'},
				'pro' => $food->pro,
			];
		}
		$ret = ProjectHealth::create([
			'user_id' => $this->user_id,
			'image' => $upload->data->url,
		]);
		$foods = $ret->predicted()->saveAll($data);
		$aaa = microtime(true) - $s;
//			$this->writeJson(0,'总计'.$aaa.'s'.'接口使用了'.$use.'s');
		$this->writeJson(['list' => $foods, 'health_id' => $ret->id]);
	}
	
	
	/**
	 * 营养健康 - 搜索
	 * @param Request $request
	 * @return void
	 */
	function healthSearch(Request $request)
	{
		$keyword = $request->get('keyword');
		$row = ProjectHealth::create(['user_id'=>$this->user_id]);
		$client = new Client();
		$search = $client->get('http://124.222.206.164:5000/search',[
			'query' =>[
				'q' => $keyword
			],
		]);
		$search = json_decode($search->getBody()->getContents());
		if (empty($search)) {
			$this->writeJson(0, '未找到相关数据');
		}
		$data = [];
		foreach ($search as $food) {
			$data[] = [
				'name' => $food->Name,
				'calcium' => $food->nutrition->{'Calcium(mg)'},
				'carbohydrates' => $food->nutrition->{'Carbohydrates(g)'},
				'cholesterol' => $food->nutrition->{'Cholesterol(mg)'},
				'copper' => $food->nutrition->{'Copper (mg)'},
				'dietary_fiber' => $food->nutrition->{'Dietary Fiber(g)'},
				'energy' => $food->nutrition->{'Energy(kcal)'},
				'fat' => $food->nutrition->{'Fat(g)'},
				'iron' => $food->nutrition->{'Iron(mg)'},
				'magnesium' => $food->nutrition->{'Magnesium (mg)'},
				'manganese' => $food->nutrition->{'Manganese(mg)'},
				'phosphorus' => $food->nutrition->{'Phosphorus (mg)'},
				'potassium' => $food->nutrition->{'Potassium(mg)'},
				'protein' => $food->nutrition->{'Protein(g)'},
				'saturated' => $food->nutrition->{'Saturated fat(g)'},
				'sodium' => $food->nutrition->{'Sodium(mg)'},
				'sugar' => $food->nutrition->{'Sugar(g)'},
				'trans_fat' => $food->nutrition->{'Trans fat(g)'},
				'vitamin_c' => $food->nutrition->{'Vitamin C(mg)'},
				'zinc' => $food->nutrition->{'Zinc(mg)'},
			];
		}
		$ret = $row->predicted()->saveAll($data);
		$this->writeJson($ret);
	}
	
	/**
	 * 营养健康-确认食物
	 * @param Request $request
	 * @return void
	 */
	function healthConfirm(Request $request)
	{
		$predicted_id = $request->post('predicted_id');
		$row = ProjectHealthPredicted::findOrFail($predicted_id);
		$ret = ProjectHealthFood::create([
			'user_id' => $this->user_id,
			'health_id' => $row->health_id,
			'name' => $row->name,
		]);
		$nutrtion = $ret->nutrtions()->save([
			'name' => $row->name,
			'calcium' => $row->calcium,
			'carbohydrates' => $row->carbohydrates,
			'cholesterol' => $row->cholesterol,
			'copper' => $row->copper,
			'dietary_fiber' => $row->dietary_fiber,
			'energy' => $row->energy,
			'fat' => $row->fat,
			'iron' => $row->iron,
			'magnesium' => $row->magnesium,
			'manganese' => $row->manganese,
			'phosphorus' => $row->phosphorus,
			'potassium' => $row->potassium,
			'protein' => $row->protein,
			'saturated' => $row->saturated,
			'sodium' => $row->sodium,
			'sugar' => $row->sugar,
			'trans_fat' => $row->trans_fat,
			'vitamin_c' => $row->vitamin_c,
			'zinc' => $row->zinc,
		]);
		$this->writeJson($nutrtion);
	}
	
	/**
	 * 营养健康-确认食物-营养设置
	 * @param Request $request
	 * @return void
	 */
	function healthNutrition(Request $request)
	{
		$id = $request->post('id/d');
		$weight = $request->post('weight');
		if (empty($id)) {
			$this->writeJson(0, '請先選擇菜式');
		}
		if (empty($weight)) {
			$this->writeJson(0, '重量不能为空或0');
		}
		$row = ProjectHealthFoodNutrition::findOrFail($id);
		$data = [
			'weight' => $weight,
			'food_id' => $row->food_id,
			'calcium' => bcmul(bcdiv($row->calcium, '100', 10), (string)$weight, 2),
			'carbohydrates' => bcmul(bcdiv($row->carbohydrates, '100', 10), (string)$weight, 2),
			'cholesterol' => bcmul(bcdiv($row->cholesterol, '100', 10), (string)$weight, 2),
			'copper' => bcmul(bcdiv($row->copper, '100', 10), (string)$weight, 2),
			'dietary_fiber' => bcmul(bcdiv($row->dietary_fiber, '100', 10), (string)$weight, 2),
			'energy' => bcmul(bcdiv($row->energy, '100', 10), (string)$weight, 2),
			'fat' => bcmul(bcdiv($row->fat, '100', 10), (string)$weight, 2),
			'iron' => bcmul(bcdiv($row->iron, '100', 10), (string)$weight, 2),
			'magnesium' => bcmul(bcdiv($row->magnesium, '100', 10), (string)$weight, 2),
			'manganese' => bcmul(bcdiv($row->manganese, '100', 10), (string)$weight, 2),
			'phosphorus' => bcmul(bcdiv($row->phosphorus, '100', 10), (string)$weight, 2),
			'potassium' => bcmul(bcdiv($row->potassium, '100', 10), (string)$weight, 2),
			'protein' => bcmul(bcdiv($row->protein, '100', 10), (string)$weight, 2),
			'saturated' => bcmul(bcdiv($row->saturated, '100', 10), (string)$weight, 2),
			'sodium' => bcmul(bcdiv($row->sodium, '100', 10), (string)$weight, 2),
			'sugar' => bcmul(bcdiv($row->sugar, '100', 10), (string)$weight, 2),
			'trans_fat' => bcmul(bcdiv($row->trans_fat, '100', 10), (string)$weight, 2),
			'vitamin_c' => bcmul(bcdiv($row->vitamin_c, '100', 10), (string)$weight, 2),
			'zinc' => bcmul(bcdiv($row->zinc, '100', 10), (string)$weight, 2),
		];
		$ret = ProjectHealthFoodNutrition::create($data);
		$this->writeJson($ret);
	}
	
	/**
	 * 幸福感问卷
	 * @return void
	 */
	function happy()
	{
		$rows = ProjectHappy::with(['children'])->where(['pid' => 0])->select();
		$this->writeJson($rows);
	}
	
	/**
	 * 幸福感问卷填写
	 * @return void
	 */
	function happyFill(Request $request)
	{
		
		if (empty($this->user_id)) {
			$this->writeJson(401, '请先登录');
		}
		$ids = $request->post('ids');
		$user = User::findOrFail($this->user_id);
		ProjectHappyOut::create([
			'user_id' => $this->user_id,
			'happy_ids' => $ids,
		]);
		JWTAuth::refresh();
		if ($user->life_out->isEmpty()) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 107]);
			$this->writeJson(107, '请先填写生活方式问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		$token = JWTAuth::builder(['user_id' => $this->user_id, 'user_status' => 1]);
		$this->writeJson(1, '', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	/**
	 * 生活方式问卷
	 * @return void
	 */
	function life()
	{
		$rows = ProjectLife::with(['children'])->where(['pid' => 0])->select();
		$this->writeJson($rows);
	}
	
	/**
	 * 生活方式问卷填写
	 * @return void
	 */
	function lifeFill(Request $request)
	{
		if (empty($this->user_id)) {
			$this->writeJson(401, '请先登录');
		}
		$ids = $request->post('ids');
		ProjectLifeOut::create([
			'user_id' => $this->user_id,
			'life_ids' => $ids,
		]);
		$user = User::findOrFail($this->user_id);
		JWTAuth::refresh();
		if ($user->happy_out->isEmpty()) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 106]);
			$this->writeJson(106, '请先填写幸福感问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		
		$token = JWTAuth::builder(['user_id' => $this->user_id, 'user_status' => 1]);
		$this->writeJson(1, '', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	
}
